<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div>第三版手写Promise</div>
    <div>用构造函数来写，前面都是用的Class</div>
  </body>
  <script>
    function MyPromise(executor) {
      var self = this
      self.data = null
      self.error = null
      self.status = 'pending'
      self.onResolvedCallback = []
      self.onRejectedCallback = []

      function resolve(value) {
        if (self.status === 'pending') {
          self.status = 'resolved'
          self.data = value
          if (self.onResolvedCallback.length > 0) {
            self.onResolvedCallback.shift()(value)
          }
        }
      }
      function reject(e) {
        if (self.status === 'pending') {
          self.status = 'rejected'
          self.error = e
          if (self.onRejectedCallback.length > 0) {
            self.onRejectedCallback.shift()(value)
          }
        }
      }

      try {
        executor(resolve, reject)
      } catch (e) {
        reject(e)
      }
    }
    MyPromise.prototype.then = function (onResolve, onReject) {
      let self = this

      let promise2

      onResolve =
        typeof onResolve === 'function'
          ? onResolve
          : function (value) {
              return value
            }
      onReject =
        typeof onReject === 'function'
          ? onReject
          : function (error) {
              throw error
            }

      if (self.status === 'resolved') {
        return (promise2 = new MyPromise((resolve, reject) => {
          queueMicrotask(() => {
            try {
              let x = onResolve(self.data)
              if (x instanceof MyPromise) {
                x.then(resolve, reject)
              }
              resolve(x)
            } catch (e) {
              reject(e)
            }
          })
        }))
      }
      if (self.status === 'rejected') {
        return (promise2 = new MyPromise((resolve, reject) => {
          try {
            let x = onReject(self.error)
            if (x instanceof MyPromise) {
              x.then(resolve, reject)
            }
            resolve(x)
          } catch (e) {
            reject(e)
          }
        }))
      }
    }
    MyPromise.prototype.catch = function (onRejected) {
      let self = this
      return self.then(null, onRejected)
    }

    let p1 = new MyPromise((resolve, reject) => {
      reject(100)
    })
    let p3 = p1
      .then()
      .then(null, (err) => console.log('error11==', err))
      .catch((error) => console.log('error22==', error))

    // let p2 = p1.catch((err) => {
    //   console.log('p1被rejected了==', err)
    // })
    // console.log('p2===', p2)
    console.log('p3===', p3)
    console.log('script end')

    // let m1 = new Promise((resolve, reject) => {
    //   resolve(200)
    // })
    // let m3 = m1.then((res) => {
    //   console.log('m3-res==', res)
    //   return Promise.reject('err==m11')
    // })
    // console.log('m3===', m3)
    // console.log('script end')
  </script>
</html>
